﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UtilZ.Dotnet.Ex.Base;

namespace UtilZ.Dotnet.Ex.Json
{
    /// <summary>
    /// json序列化中心-反序列化
    /// </summary>
    public partial class JsonSerializerCore
    {
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="targetType">目标类型</param>
        /// <param name="json">json格式字符串</param>
        /// <param name="obj">json值要填充的对象</param>
        /// <exception cref="ApplicationException">内部逻辑错误异常</exception>
        /// <exception cref="NotImplementedException">未实现的数据类型异常</exception>
        public void Deserialize(Type targetType, ref string json, ref object obj)
        {
            if (json == null || JsonHelper.IsNull(json))
            {
                if (!JsonHelper.AllowNull(targetType))
                {
                    throw new ArgumentNullException($"类型\"{targetType.FullName}\"值不允许为null,转换失败", nameof(json));
                }

                obj = null;
                return;
            }

            JsonNode jsonNode = this.GetJsonNode(targetType);
            int maxIndex = json.Length;
            int currentIndex = 0;

            JsonCommentType commentType = JsonHelper.CommentBegin(ref json, currentIndex);
            if (commentType != JsonCommentType.None)
            {
                JsonHelper.IgnoreComment(commentType, ref json, ref currentIndex);
            }

            switch (json[currentIndex])
            {
                case '{':
                    currentIndex += 1;
                    //Object对象和IDictionary序列化结构
                    switch (jsonNode.TypeCategory)
                    {
                        case TypeCategorys.Object:
                            if (obj == null)
                            {
                                obj = Activator.CreateInstance(jsonNode.Type);
                            }
                            this.ReadJsonObject(ref json, ref currentIndex, maxIndex, jsonNode, ref obj);
                            break;
                        case TypeCategorys.IDictionary:
                            IDictionary dic = this.ReadJsonIDictionary(ref json, ref currentIndex, maxIndex, jsonNode);
                            if (dic != null)
                            {
                                if (obj == null)
                                {
                                    obj = dic;
                                }
                                else
                                {
                                    IDictionary srcDic = (IDictionary)obj;
                                    foreach (var key in dic.Keys)
                                    {
                                        srcDic.Add(key, dic[key]);
                                    }
                                }
                            }

                            break;
                        default:
                            throw new ArgumentException($"json值与预期不符合,期望值类型为\"{TypeCategorys.Object.ToString()}\"或\"{TypeCategorys.IDictionary.ToString()}\"");
                    }
                    break;
                case '[':
                    currentIndex += 1;
                    //IList序列化结构
                    if (jsonNode.TypeCategory != TypeCategorys.IList)
                    {
                        throw new ArgumentException($"json值与预期不符合,期望值类型为\"{TypeCategorys.IList.ToString()}\"");
                    }

                    IList list = this.ReadJsonIList(ref json, ref currentIndex, maxIndex, jsonNode);
                    if (list != null)
                    {
                        if (obj == null)
                        {
                            obj = list;
                        }
                        else
                        {
                            if (obj is Array)
                            {
                                Array srcArr = (Array)obj;
                                Array newArr = (Array)list;
                                Type eleType = obj.GetType().GetGenericArguments().FirstOrDefault();
                                Array dstArr = Array.CreateInstance(eleType, srcArr.Length + newArr.Length);
                                Array.Copy(srcArr, dstArr, srcArr.Length);
                                Array.Copy(newArr, 0, dstArr, srcArr.Length, newArr.Length);
                                obj = dstArr;
                            }
                            else
                            {
                                IList srcList = (IList)obj;
                                foreach (var item in list)
                                {
                                    srcList.Add(item);
                                }
                            }
                        }
                    }
                    break;
                default:
                    //简单数据类型直接序列化的结果
                    if (jsonNode.TypeCategory != TypeCategorys.Basic)
                    {
                        throw new ArgumentException($"json值与预期不符合,期望值类型为\"{TypeCategorys.Basic.ToString()}\"");
                    }

                    IJsonValueConverter converter = JsonConverterManger.GetDefaultConverter(jsonNode.Type);
                    string valueStr = currentIndex == 0 ? json : json.Substring(currentIndex);
                    if (!converter.TryConvertFrom(null, jsonNode.Type, null, valueStr, out obj))
                    {
                        throw new ArgumentException($"json值\"{json}\"转换为类型{jsonNode.Type.DeclaringType.FullName}值失败");
                    }
                    break;
            }
        }




        private IList ReadJsonIList(ref string json, ref int currentIndex, int maxIndex, JsonNode jsonNode)
        {
            JsonOriginValueTypes? originValueType = null;
            IList objList;
            if (jsonNode.Type.IsArray)
            {
                objList = new List<object>();
            }
            else
            {
#if NET4_0
                Type[] genericTypeArguments = jsonNode.Type.GetGenericArguments();
#else
                Type[] genericTypeArguments = jsonNode.Type.GenericTypeArguments;
#endif

                objList = this.CreateIList(jsonNode.Type, 0);
                if (genericTypeArguments != null &&
                    genericTypeArguments.Length == 1 &&
                    genericTypeArguments[0].IsPrimitive &&
                    genericTypeArguments[0].IsValueType)
                {
                    originValueType = JsonOriginValueTypes.Value;
                }
            }

            int valueBeingIndex = currentIndex;
            string value;
            TokenQuoteMarkType tokenQuoteMarkType = TokenQuoteMarkType.None;
            int doubleQuotesBeginIndex = -1;
            var itemNode = jsonNode.Children.First();

            for (int i = currentIndex; i < maxIndex; i++)
            {
                if (json[i] == '[')
                {
                    //嵌套集合
                    originValueType = JsonOriginValueTypes.IList;
                    valueBeingIndex = i + 1;
                    var list = this.ReadJsonIList(ref json, ref valueBeingIndex, maxIndex, itemNode);
                    objList.Add(list);
                    i = valueBeingIndex;
                }
                else if (json[i] == '{')
                {
                    //嵌套对象
                    originValueType = JsonOriginValueTypes.Object;
                    valueBeingIndex = i + 1;
                    var obj = Activator.CreateInstance(itemNode.Type);
                    this.ReadJsonObject(ref json, ref valueBeingIndex, maxIndex, itemNode, ref obj);
                    objList.Add(obj);
                    i = valueBeingIndex;
                }
                else if (json[i] == '"' || json[i] == '\'')
                {
                    //单双引号值集合,eg:['四川'、"2000-04-05T12:25:36"]
                    if (doubleQuotesBeginIndex < 0)
                    {
                        doubleQuotesBeginIndex = i;
                        originValueType = JsonOriginValueTypes.String;
                        tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                    }
                    else
                    {
                        if (json[i] == '"' && json[i - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                            json[i] == '\'' && json[i - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                        {
                            value = json.Substring(doubleQuotesBeginIndex + 1, i - doubleQuotesBeginIndex - 1).Trim();
                            value = JsonHelper.DeEscape(tokenQuoteMarkType, value);
                            doubleQuotesBeginIndex = -1;
                            this.SetIListValue(itemNode, objList, value);
                        }
                    }
                }
                else if (json[i] == ',')
                {
                    if (originValueType.HasValue && originValueType != JsonOriginValueTypes.Value)
                    {
                        continue;
                    }

                    //简单数据类型值,eg:[true、null、123]
                    originValueType = JsonOriginValueTypes.Value;
                    value = json.Substring(valueBeingIndex, i - valueBeingIndex).Trim();
                    valueBeingIndex = i + 1;
                    this.SetIListValue(itemNode, objList, value);
                }
                else if (json[i] == ']')
                {
                    if (originValueType == JsonOriginValueTypes.Value)
                    {
                        value = json.Substring(valueBeingIndex, i - valueBeingIndex).Trim();
                        if (originValueType == JsonOriginValueTypes.String)
                        {
                            value = JsonHelper.DeEscape(TokenQuoteMarkType.None, value);
                        }

                        valueBeingIndex = i + 1;
                        if (!string.IsNullOrEmpty(value))
                        {
                            this.SetIListValue(itemNode, objList, value);
                        }
                    }

                    currentIndex = i;
                    break;
                }
            }

            if (originValueType == null)
            {
                originValueType = JsonOriginValueTypes.Empty;
            }


            //如果集合类型是数组,重新创建数组
            if (jsonNode.Type.IsArray)
            {
                IList arr = this.CreateIList(jsonNode.Type, objList.Count);
                for (int i = 0; i < objList.Count; i++)
                {
                    arr[i] = objList[i];
                }
                objList = arr;
            }

            return objList;
        }

        private void SetIListValue(JsonNode jsonNode, IList list, string value)
        {
            if (jsonNode.ValueConverter.TryConvertFrom(jsonNode.ObjectMemberInfo, jsonNode.Type, list, value, out object objValue))
            {
                list.Add(objValue);
            }
            else
            {
                throw new ArgumentException($"json值\"{value}\"转换为类型\"{jsonNode.Type.FullName}\"值失败");
            }
        }



        private IDictionary ReadJsonIDictionary(ref string json, ref int currentIndex, int maxIndex, JsonNode jsonNode)
        {
            int nameBeginIndex = -1, valueBeingIndex;
            string name = null, value;
            TokenQuoteMarkType tokenQuoteMarkType = TokenQuoteMarkType.None;
            bool requireFindMaohao = true, breakAll = false;
            int objectMinIndex;
            JsonNode eleNode;
            IDictionary dic = (IDictionary)Activator.CreateInstance(jsonNode.Type);

            for (int i = currentIndex; i < maxIndex; i++)
            {
                if (name == null)
                {
                    if (nameBeginIndex < 0)
                    {
                        //查找名称开始
                        if (json[i] == '"' || json[i] == '\'')
                        {
                            nameBeginIndex = i + 1;
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                        }
                        else if (json[i] == '}')
                        {
                            //当发现右大括号,说明当前对象已经处理完成
                            currentIndex = i;
                            break;
                        }
                    }
                    else
                    {
                        //查找名称结束
                        if (json[i] == '"' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                            json[i] == '\'' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                        {
                            name = json.Substring(nameBeginIndex, i - nameBeginIndex);
                            nameBeginIndex = -1;
                            requireFindMaohao = true;
                        }
                    }
                }
                else
                {
                    if (requireFindMaohao)
                    {
                        if (json[i] == ':')
                        {
                            requireFindMaohao = false;
                        }
                    }
                    else
                    {
                        if (json[i] == ' ')
                        {
                            continue;
                        }

                        if (json[i] == '[')
                        {
                            //嵌套IList
                            objectMinIndex = i + 1;
                            eleNode = jsonNode.Children.First();
                            object list = this.ReadJsonIList(ref json, ref objectMinIndex, maxIndex, eleNode);
                            this.SetDictionaryValue(eleNode, dic, ref name, ref list);
                            i = objectMinIndex;
                            name = null;
                        }
                        else if (json[i] == '{')
                        {
                            //嵌套对象
                            objectMinIndex = i + 1;
                            eleNode = jsonNode.Children.First();
                            switch (eleNode.TypeCategory)
                            {
                                case TypeCategorys.Object:
                                    var obj = Activator.CreateInstance(eleNode.Type);
                                    this.ReadJsonObject(ref json, ref objectMinIndex, maxIndex, eleNode, ref obj);
                                    this.SetDictionaryValue(eleNode, dic, ref name, ref obj);
                                    break;
                                case TypeCategorys.IDictionary:
                                    object dic2 = this.ReadJsonIDictionary(ref json, ref objectMinIndex, maxIndex, eleNode);
                                    this.SetDictionaryValue(eleNode, dic, ref name, ref dic2);
                                    break;
                                default:
                                    throw new ArgumentException($"json值与预期不符合,期望值类型为\"{TypeCategorys.Object.ToString()}\"或\"{TypeCategorys.IDictionary.ToString()}\"");
                            }

                            i = objectMinIndex;
                            name = null;
                        }
                        else if (json[i] == '"' || json[i] == '\'')
                        {
                            //单双引号值,eg:'四川'、"2000-04-05T12:25:36"
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                            valueBeingIndex = i;

                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == '"' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                                    json[j] == '\'' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                                {
                                    value = json.Substring(valueBeingIndex + 1, j - valueBeingIndex - 1);
                                    value = JsonHelper.DeEscape(tokenQuoteMarkType, value);
                                    this.SetDictionaryValue(jsonNode, dic, ref name, ref value);
                                    name = null;
                                    i = j;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            //简单数据类型值,eg:null、123
                            valueBeingIndex = i;
                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == ',')
                                {
                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    this.SetDictionaryValue(jsonNode, dic, ref name, ref value);
                                    name = null;
                                    i = j;
                                    break;
                                }
                                else if (json[j] == '}')
                                {
                                    //嵌套对象结束
                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    this.SetDictionaryValue(jsonNode, dic, ref name, ref value);
                                    name = null;
                                    currentIndex = j;
                                    breakAll = true;
                                    break;
                                }
                            }

                            if (breakAll)
                            {
                                break;
                            }
                        }
                    }

                }
            }

            return dic;
        }

        private void SetDictionaryValue(JsonNode dicEleNode, IDictionary dic, ref string name, ref object value)
        {
            object key;
            if (dicEleNode.KeyType == TypeEx.StringType)
            {
                key = name;
            }
            else
            {
                key = ConvertEx.ConvertToObject(dicEleNode.KeyType, name);
            }
            dic.Add(key, value);
        }

        private void SetDictionaryValue(JsonNode jsonNode, IDictionary dic, ref string name, ref string value)
        {
            var dicEleNode = jsonNode.Children.First();
            if (dicEleNode.ValueConverter.TryConvertFrom(dicEleNode.ObjectMemberInfo, dicEleNode.Type, dic, value, out object objValue))
            {
                this.SetDictionaryValue(dicEleNode, dic, ref name, ref objValue);
            }
            else
            {
                throw new ArgumentException($"json值\"{value}\"转换为类型\"{dicEleNode.Type.FullName}\"值失败");
            }
        }




        private void ReadJsonObject(ref string json, ref int currentIndex, int maxIndex, JsonNode jsonNode, ref object obj)
        {
            int nameBeginIndex = -1, valueBeingIndex;
            string name = null, value;
            TokenQuoteMarkType tokenQuoteMarkType = TokenQuoteMarkType.None;
            bool requireFindMaohao = true, breakAll = false;
            int objectMinIndex;
            JsonCommentType commentType;

            for (int i = currentIndex; i < maxIndex; i++)
            {
                if (name == null)
                {
                    if (nameBeginIndex < 0)
                    {
                        //查找名称开始
                        if (json[i] == '"' || json[i] == '\'')
                        {
                            nameBeginIndex = i + 1;
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                        }
                        else if (json[i] == '}')
                        {
                            //当发现右大括号,说明当前对象已经处理完成
                            currentIndex = i;
                            break;
                        }
                        else if (json[i] == ' ')
                        {
                            //忽略空格
                            continue;
                        }
                        else
                        {
                            commentType = JsonHelper.CommentBegin(ref json, i);
                            if (commentType != JsonCommentType.None)
                            {
                                //忽略注释
                                JsonHelper.IgnoreComment(commentType, ref json, ref i);
                                continue;
                            }
                        }
                    }
                    else
                    {
                        //查找名称结束
                        if (json[i] == '"' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                            json[i] == '\'' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                        {
                            name = json.Substring(nameBeginIndex, i - nameBeginIndex);
                            nameBeginIndex = -1;
                            requireFindMaohao = true;
                        }
                    }
                }
                else
                {
                    if (requireFindMaohao)
                    {
                        if (json[i] == ':')
                        {
                            requireFindMaohao = false;
                        }
                    }
                    else
                    {
                        if (json[i] == ' ')
                        {
                            continue;
                        }

                        if (json[i] == '[')
                        {
                            //嵌套IList
                            objectMinIndex = i + 1;
                            if (jsonNode.Children.TryGetValue(name, out var listNode))
                            {
                                IList list = this.ReadJsonIList(ref json, ref objectMinIndex, maxIndex, listNode);
                                listNode.SetValue(ref obj, list);
                            }
                            else
                            {
                                this.ParseIList(ref json, ref objectMinIndex, maxIndex);
                            }
                            i = objectMinIndex;
                            name = null;
                        }
                        else if (json[i] == '{')
                        {
                            //嵌套对象
                            objectMinIndex = i + 1;
                            if (jsonNode.Children.TryGetValue(name, out var objectNode))
                            {
                                switch (objectNode.TypeCategory)
                                {
                                    case TypeCategorys.Object:
                                        var obj2 = Activator.CreateInstance(objectNode.Type);
                                        this.ReadJsonObject(ref json, ref objectMinIndex, maxIndex, objectNode, ref obj2);
                                        objectNode.SetValue(ref obj, obj2);
                                        break;
                                    case TypeCategorys.IDictionary:
                                        IDictionary dic = this.ReadJsonIDictionary(ref json, ref objectMinIndex, maxIndex, objectNode);
                                        objectNode.SetValue(ref obj, dic);
                                        break;
                                    default:
                                        throw new ArgumentException($"json值与预期不符合,期望值类型为\"{TypeCategorys.Object.ToString()}\"或\"{TypeCategorys.IDictionary.ToString()}\"");
                                }
                            }
                            else
                            {
                                this.ParseObject(ref json, ref objectMinIndex, maxIndex);
                            }

                            i = objectMinIndex;
                            name = null;
                        }
                        else if (json[i] == '"' || json[i] == '\'')
                        {
                            //单双引号值,eg:'四川'、"2000-04-05T12:25:36"
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                            valueBeingIndex = i;

                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == '"' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                                    json[j] == '\'' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                                {
                                    value = json.Substring(valueBeingIndex + 1, j - valueBeingIndex - 1);
                                    value = JsonHelper.DeEscape(tokenQuoteMarkType, value);
                                    this.SetBasicValue(jsonNode, ref obj, ref name, ref value);
                                    name = null;
                                    i = j;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            //简单数据类型值,eg:null、123
                            valueBeingIndex = i;
                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == ',')
                                {
                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    this.SetBasicValue(jsonNode, ref obj, ref name, ref value);
                                    name = null;
                                    i = j;
                                    break;
                                }
                                else if (json[j] == '}')
                                {
                                    //嵌套对象结束
                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    this.SetBasicValue(jsonNode, ref obj, ref name, ref value);
                                    name = null;
                                    currentIndex = j;
                                    breakAll = true;
                                    break;
                                }
                            }

                            if (breakAll)
                            {
                                break;
                            }
                        }
                    }

                }
            }
        }



        /// <summary>
        /// 解析IList序列化结构
        /// </summary>
        /// <param name="json"></param>
        /// <param name="currentIndex"></param>
        /// <param name="maxIndex"></param>
        /// <returns></returns>
        private JElement ParseIList(ref string json, ref int currentIndex, int maxIndex)
        {
            var list = new List<JElement>();
            int valueBeingIndex = currentIndex;
            JElement jsonElement;
            string value;
            TokenQuoteMarkType tokenQuoteMarkType = TokenQuoteMarkType.None;
            JsonOriginValueTypes? originValueType = null;
            int doubleQuotesBeginIndex = -1;

            for (int i = currentIndex; i < maxIndex; i++)
            {
                if (json[i] == '[')
                {
                    //嵌套集合
                    originValueType = JsonOriginValueTypes.IList;
                    valueBeingIndex = i + 1;
                    jsonElement = this.ParseIList(ref json, ref valueBeingIndex, maxIndex);
                    list.Add(jsonElement);
                    i = valueBeingIndex;
                }
                else if (json[i] == '{')
                {
                    //嵌套对象
                    originValueType = JsonOriginValueTypes.Object;
                    valueBeingIndex = i + 1;
                    jsonElement = this.ParseObject(ref json, ref valueBeingIndex, maxIndex);
                    list.Add(jsonElement);
                    i = valueBeingIndex;
                }
                else if (json[i] == '"' || json[i] == '\'')
                {
                    //双引号值集合,eg:["四川","2000-04-05T12:25:36",'abc']
                    if (doubleQuotesBeginIndex < 0)
                    {
                        doubleQuotesBeginIndex = i;
                        tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                        originValueType = JsonOriginValueTypes.String;
                    }
                    else
                    {
                        if (json[i] == '"' && json[i - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                            json[i] == '\'' && json[i - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                        {
                            value = json.Substring(doubleQuotesBeginIndex + 1, i - doubleQuotesBeginIndex - 1).Trim();
                            value = JsonHelper.DeEscape(tokenQuoteMarkType, value);
                            doubleQuotesBeginIndex = -1;
                            jsonElement = new JElement(originValueType.Value, value);
                            list.Add(jsonElement);
                        }
                    }
                }
                else if (json[i] == ',')
                {
                    if (originValueType.HasValue && originValueType != JsonOriginValueTypes.Value)
                    {
                        continue;
                    }

                    //简单数据类型值,eg:[true、null、123]
                    originValueType = JsonOriginValueTypes.Value;
                    value = json.Substring(valueBeingIndex, i - valueBeingIndex).Trim();
                    valueBeingIndex = i + 1;
                    jsonElement = new JElement(originValueType.Value, value);
                    list.Add(jsonElement);
                }
                else if (json[i] == ']')
                {
                    if (originValueType == JsonOriginValueTypes.Value)
                    {
                        value = json.Substring(valueBeingIndex, i - valueBeingIndex).Trim();
                        if (originValueType == JsonOriginValueTypes.String)
                        {
                            value = JsonHelper.DeEscape(TokenQuoteMarkType.None, value);
                        }

                        valueBeingIndex = i + 1;
                        jsonElement = new JElement(originValueType.Value, value);
                        list.Add(jsonElement);
                    }

                    currentIndex = i;
                    break;
                }
            }

            if (originValueType == null)
            {
                originValueType = JsonOriginValueTypes.Empty;
            }

            return new JElement(new JElementCollection(originValueType.Value, list));
        }

        /// <summary>
        /// 解析Object对象和IDictionary序列化结构
        /// </summary>
        /// <param name="json"></param>
        /// <param name="currentIndex"></param>
        /// <param name="maxIndex"></param>
        /// <returns></returns>
        private JElement ParseObject(ref string json, ref int currentIndex, int maxIndex)
        {
            var objEleDic = new Dictionary<string, JElement>();
            JElement jsonElement;
            int nameBeginIndex = -1, valueBeingIndex;
            string name = null, value;
            TokenQuoteMarkType tokenQuoteMarkType = TokenQuoteMarkType.None;
            bool requireFindMaohao = true, breakAll = false;
            int objectMinIndex;
            JsonCommentType commentType;

            for (int i = currentIndex; i < maxIndex; i++)
            {
                if (name == null)
                {
                    if (nameBeginIndex < 0)
                    {
                        //查找名称开始
                        if (json[i] == '\'' || json[i] == '"')
                        {
                            nameBeginIndex = i + 1;
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                        }
                        else if (json[i] == '}')
                        {
                            //当发现右大括号,说明当前对象已经处理完成
                            currentIndex = i;
                            break;
                        }
                        else if (json[i] == ' ')
                        {
                            //忽略空格
                            continue;
                        }
                        else
                        {
                            commentType = JsonHelper.CommentBegin(ref json, i);
                            if (commentType != JsonCommentType.None)
                            {
                                //忽略注释
                                JsonHelper.IgnoreComment(commentType, ref json, ref i);
                                continue;
                            }
                        }
                    }
                    else
                    {
                        //查找名称结束
                        if (json[i] == '"' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                            json[i] == '\'' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                        {
                            name = json.Substring(nameBeginIndex, i - nameBeginIndex);
                            nameBeginIndex = -1;
                            requireFindMaohao = true;
                        }
                    }
                }
                else
                {
                    if (requireFindMaohao)
                    {
                        if (json[i] == ':')
                        {
                            requireFindMaohao = false;
                        }
                    }
                    else
                    {
                        if (json[i] == ' ')
                        {
                            continue;
                        }

                        if (json[i] == '[')
                        {
                            //嵌套IList
                            objectMinIndex = i + 1;
                            jsonElement = this.ParseIList(ref json, ref objectMinIndex, maxIndex);
                            i = objectMinIndex;
                            objEleDic.Add(name, jsonElement);
                            name = null;
                        }
                        else if (json[i] == '{')
                        {
                            //嵌套对象
                            objectMinIndex = i + 1;
                            jsonElement = this.ParseObject(ref json, ref objectMinIndex, maxIndex);
                            i = objectMinIndex;
                            objEleDic.Add(name, jsonElement);
                            name = null;
                        }
                        else if (json[i] == '"' || json[i] == '\'')
                        {
                            //单双引号值,eg:'四川'、"2000-04-05T12:25:36"
                            tokenQuoteMarkType = json[i] == '"' ? TokenQuoteMarkType.DoubleQuoteMark : TokenQuoteMarkType.SingleQuoteMark;
                            valueBeingIndex = i;

                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == '"' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.DoubleQuoteMark ||
                                    json[j] == '\'' && json[j - 1] != '\\' && tokenQuoteMarkType == TokenQuoteMarkType.SingleQuoteMark)
                                {
                                    value = json.Substring(valueBeingIndex + 1, j - valueBeingIndex - 1);

                                    value = JsonHelper.DeEscape(tokenQuoteMarkType, value);
                                    jsonElement = new JElement(JsonOriginValueTypes.String, name, value);
                                    objEleDic.Add(name, jsonElement);
                                    name = null;
                                    i = j;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            //简单数据类型值,eg:null、123
                            valueBeingIndex = i;
                            for (int j = i + 1; j < maxIndex; j++)
                            {
                                if (json[j] == ',')
                                {
                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    if (JsonHelper.IsNull(value))
                                    {
                                        jsonElement = new JElement(JsonOriginValueTypes.Null, name, value);
                                    }
                                    else
                                    {
                                        jsonElement = new JElement(JsonOriginValueTypes.Value, name, value);
                                    }

                                    objEleDic.Add(name, jsonElement);
                                    name = null;
                                    i = j;
                                    break;
                                }
                                else if (json[j] == '}')
                                {
                                    //嵌套对象结束

                                    value = json.Substring(valueBeingIndex, j - valueBeingIndex).Trim();
                                    if (JsonHelper.IsNull(value))
                                    {
                                        jsonElement = new JElement(JsonOriginValueTypes.Null, name, value);
                                    }
                                    else
                                    {
                                        jsonElement = new JElement(JsonOriginValueTypes.Value, name, value);
                                    }

                                    objEleDic.Add(name, jsonElement);
                                    name = null;
                                    currentIndex = j;
                                    breakAll = true;
                                    break;
                                }
                            }

                            if (breakAll)
                            {
                                break;
                            }
                        }
                    }

                }
            }

            return new JElement(objEleDic);
        }



        private void SetBasicValue(JsonNode jsonNode, ref object obj, ref string name, ref string value)
        {
            if (jsonNode.Children.TryGetValue(name, out JsonNode node))
            {
                if (JsonHelper.IsNull(value))
                {
                    node.SetValue(ref obj, null);
                }
                else
                {
                    if (node.ValueConverter.TryConvertFrom(node.ObjectMemberInfo, node.Type, obj, value, out object objValue))
                    {
                        node.SetValue(ref obj, objValue);
                    }
                    else
                    {
                        throw new ArgumentException($"json值\"{value}\"转换为类型\"{node.Type.FullName}\"值失败");
                    }
                }
            }
        }

        private IList CreateIList(Type ilistType, int eleCount)
        {
            IList list;
            if (ilistType.IsArray)
            {
                Type eleType = TypeEx.GetIListElementType(ilistType);
                list = Array.CreateInstance(eleType, eleCount);
            }
            else
            {
                list = ActivatorEx.CreateInstance<IList>(ilistType);
            }

            return list;
        }
    }
}
